//1.整体含义：char *(*p) 声明了一个指针 p，它指向另一个指针，而那个指针指向 char 类型。简单来说，p 是一个指向字符串指针的指针。

// 4.野指针
// 指向一块未知的区域的指针，都被称为野指针。野指针是危险的。
// 两种情况会出现野指针：
// ①声明指针时未对其初始化;
// int *p;//p就是一个野指针，如果声明时不知道哪个地址，应该指向NULL；
// int *p = NULL;int *P = a;错误！永远不要解引用NULL指针
// ②使用free函数时，没有将指针置空
// int *p =malloc(100);//申请100个字节空间
// free(p);//释放空间
// p = NULL;//如果没有将p置NULL,p就会形成野指针

/*char **p的数据类型就是char ** ，*被称为解引用符*/

//2.指针是用于存地址的，所以不能直接将数值直接赋值给指针，如：
int a = 5;int *p = a;//这样就错了，a不是地址，不可以这样写
//正确写法：
int a = 5;int *p = &a;//这样取地址a就可以把取得的地址赋值给指针p了


#include <stdio.h>

int main() {
    char str[] = "Hello";  // 一个字符串
    char *ptr = str;       // 指向字符串的指针
    char *(*p) = &ptr;     // 指向指针的指针,完全等价于char **p,括号提高可阅读性

    // 通过 p 访问字符串
    printf("直接输出: %s\n", ptr);
    printf("通过 p 输出: %s\n", *p);

    return 0;
}


//3.指针运算：    
int arr[5]={1,2,3,4,5};

int (*p)[5];
p = &arr;

int *p = arr;//指向数组的首元素地址
int *q = &arr[4];//指向数组最后一个元素的地址

printf("%d\n",*p);//1
printf("%d\n",*(p+1));//2

printf("%d\n",*q);//5
printf("%d\n",*(q-1));//4

printf("%ld",q-p);//两个指针相减的结果就是这两个指针相隔的元素个数

printf("%d\n",*++p);//++会使p本身发生改变
printf("%d\n",*--q);//--会使q本身发生改变

printf("%d\n",*(arr+1));//数组名可以加
printf("%d\n",*(arr-1));//但数组名不可以减


